#include "MyString.h"
#include <cstring>
#include <cstdbool>
MyString::MyString():size(0),capacity(15)
{
    s = new char[capacity];
}

MyString::MyString(const char *str)
{
    size = strlen(str);
    capacity = size + 1 > 15 ? size + 1 : 15;
    s= new char[capacity];
    strcpy(s,str);

    // int size = strlen(str);
    // if (size < 15)
    // {
    //     s = new char[15];
    //     this->capacity=15;
    //     strcpy(this->s, str);
    // }
    // else
    // {
    //     s = new char[size];
    //     this->capacity = size;
    //     strncpy(this->s, str, size);
    // }
    // this->size = size;
}

MyString::MyString(const MyString &string)
{
    size = string.size;
    capacity = string.capacity;
    s = new char[capacity];
    strcpy(s,string.s);
}
MyString& MyString::operator=(const MyString &string)
{
    delete []s;
    size = string.size;
    capacity = string.capacity;
    s = new char[capacity];
    strcpy(s,string.s);
    return *this;
}

MyString::~MyString()
{
    delete []s;
}

MyString& MyString::operator+=(const MyString& string)
{
    size+=string.size;
    if(size + 1 > capacity)
    {
        ReSize(size + 1);
    }
    strcat(this->s,string.s);
    return *this;
}

MyString& MyString::operator+=(const char& c)
{
    if(size + 1 > capacity)
        ReSize(capacity * 2);
    this->s[size++] = c;
    this->s[size] = '\0';
    return *this;
}

MyString MyString::operator+(const MyString &string)
{
    MyString result = *this;
    result += string;
    return result;
}

MyString &MyString::operator-=(const MyString &string)
{
    char *dest = strstr(this->s,string.s);
    while(dest != nullptr)
    {
        char *back = dest + string.size;
        while(*back != '\0')
        {
            *dest++ = *back++;
        }
        *dest = '\0';
        this->size -= string.size;
        dest = strstr(this->s, string.s);
    }

    if(size + 1 < capacity /2)
        ReSize(capacity /2);
    return *this;
}

MyString MyString::operator-(const MyString &string)
{
    MyString result = *this;
    result -= string;
    return result;
}

bool MyString::operator==(const MyString &string)
{
    return strcmp(s,string.s) == 0;
}

bool MyString::operator!=(const MyString &string)
{
    return strcmp(s,string.s) != 0;
}

bool MyString::operator&&(const MyString &string)
{
    return this->size != 0 && string.size != 0;
}

MyString::operator int()
{
    return atoi(this->s);
}

MyString::operator double()
{
    return atof(this->s);
}

MyStringArray MyString::split(const MyString &delim)
{
    MyString temp = *this;
    MyStringArray result;
    char *dest = strtok(temp.s,delim.s);
    while(dest != nullptr)
    {
        result += dest;
        dest = strtok(nullptr, delim.s);
    }
    return result;
}

char &MyString::operator[](int index)
{
    return this->s[index];
}

void MyString::ReSize(int capacity)
{
    this->capacity = capacity;
    char *newS = new char[capacity];
    size = size > capacity - 1 ? capacity - 1 : size;
    strncpy(newS,s,size);
    delete []s;
    s = newS; 
}

std::ostream& operator<<(std::ostream& os,const MyString& string)
{
    os<<string.s;
    return os;
}

std::istream& operator>>(std::istream& is,MyString &string)
{
    char c = 0;
    while((c = getchar()) != '\n' && c != ' ')
    {
        string += c;
    }
    return is;
}



MyStringArray::MyStringArray():size(0),capacity(15)
{
    array = new MyString[capacity];
}


MyStringArray::MyStringArray(const MyStringArray &a)
{
    size = a.size;
    capacity = a.capacity;
    array = new MyString[capacity];
    for(int i = 0; i < size; i++)
    {
        array[i] = a.array[i];
    }
}

MyStringArray &MyStringArray::operator=(const MyStringArray &a)
{
    delete []array;
    size = a.size;
    capacity = a.capacity;
    array = new MyString[capacity];
    for(int i = 0; i < size; i++)
    {
        array[i] = a.array[i];
    }
    return *this;
}

MyStringArray::~MyStringArray()
{
    delete []array;
}

MyStringArray &MyStringArray::operator+=(const MyString &str)
{
    if(size == capacity)
    {
        capacity *= 2;
        MyString *newS =new MyString[capacity];
        for(int i = 0; i < size; i++)
        {
            newS[i] = array[i];
        }
        delete []array;
        array = newS;
    }
    array[size++] = str;
    return *this;
}

MyStringArray MyStringArray::operator+(const MyString &a)
{
    MyStringArray result = *this;
    result += a;
    return result;
}

MyStringArray& MyStringArray::operator-=(const MyString &str)
{
    for(int i = 0; i < size; i++)
    {
        if(array[i] == str)
        {
            for(int j = i; j < size - 1; j++)
            {
                array[j] = array[j+1];
            }
            size--;
            i--;   
        }
    }
    if(size + 1 < capacity /2)
    {
        capacity /= 2;
        MyString *newS = new MyString[capacity];
        for(int i = 0; i < size; i++)
        {
            newS[i] = array[i];
        }
        delete []array;
        array = newS;
    }         
    return *this;
}

MyStringArray MyStringArray::operator-(const MyString &str)
{
    MyStringArray result = *this;
    result -= str;
    return result;
}

bool MyStringArray::operator==(const MyStringArray &a)
{
    if(size != a.size)
    {
        return false;
    }
    for(int i = 0; i < size; i++)
    {
        if(array[i] != a.array[i])
        {
            return false;
        }
    }
    return true;
}

bool MyStringArray::operator!=(const MyStringArray &a)
{
    return !(*this == a);
}

MyString &MyStringArray::operator[](int index)
{
    return array[index];
}

void MyStringArray::ReSize(int capacity)
{
    this->capacity = capacity;
    MyString *newS = new MyString[capacity];
    for (int i = 0; i < size; i++)
    {
        newS[i] = array[i];
    }
    delete[] array;
    array = newS;
}

std::ostream &operator<<(std::ostream &os, const MyStringArray &a)
{
    for(int i = 0; i < a.size; i++)
    {
        os<<a.array[i];
    }
    return os;
}

std::istream &operator>>(std::istream &is, MyStringArray &a)
{
    int size = 0;
    std ::cout << "请输入数组大小: " << std ::endl;
    std::cin >> size;
    std ::cout << "请输入数组元素: " << std ::endl;
    for (int i = 0; i < size + 1; i++)
    {
        MyString str;
        std::cin >> str;
        a.array[i] = str;
        a.size++;
    }
    std ::cout << "size = " << a.size << std ::endl;
    return is;
}
